home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 22
/
Amiga Format AFCD22 (Jan 1998, Issue 106).iso
/
-in_the_mag-
/
converters
/
graphics
/
netpbm
/
hpcdtoppm.0.6
/
src
/
postscr.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-11-16
|
10KB
|
406 lines
/* hpcdtoppm (Hadmut's pcdtoppm) v0.6
* Copyright (c) 1992, 1993, 1994 by Hadmut Danisch (danisch@ira.uka.de).
* Permission to use and distribute this software and its
* documentation for noncommercial use and without fee is hereby granted,
* provided that the above copyright notice appear in all copies and that
* both that copyright notice and this permission notice appear in
* supporting documentation. It is not allowed to sell this software in
* any way. This software is not public domain.
*/
#include "hpcdtoppm.h"
#define DITH_NEUTR 128
FLTPT PAPER_LEFT =DEF_PAPER_LEFT;
FLTPT PAPER_BOTTOM =DEF_PAPER_BOTTOM;
FLTPT PAPER_WIDTH =DEF_PAPER_WIDTH;
FLTPT PAPER_HEIGHT =DEF_PAPER_HEIGHT;
FLTPT PRINTER_XDPI =DEF_DPI;
FLTPT PRINTER_YDPI =DEF_DPI;
FLTPT PRINTER_FAK =1.0;
sINT PSIZE_SET=0,DPI_SET=0,FAK_SET=0;
static char pshdr[]="%%Creator: hpcdtoppm v0.6\n";
static char hex[]="0123456789ABCDEF";
#define HEX(x) {fputc(hex[((x)>>4)&0xf],fout);fputc(hex[(x)&0xf],fout);}
/* find an appropriate scaling coefficient and generate a ps header
* including a BoundingBox comment and a translate/scale sequence to
* fit the pixw*pixh image into a square on paper with PS user coordinates
* x,y,w,h
*/
static void size_dependant(FILE *fout,sINT pixw,sINT pixh,
FLTPT x,FLTPT y,FLTPT w,FLTPT h)
{ FLTPT scale=(FLTPT)w/pixw,scaley=(FLTPT)h/pixh;
if(scale>scaley) scale=scaley;
x+=w/2.0;y+=h/2.0;
fprintf(fout,"%%%%BoundingBox: %.8g %.8g %.8g %.8g\n",
x-scale*pixw/2.0,y-scale*pixh/2.0,
x+scale*pixw/2.0,y+scale*pixh/2.0);
fprintf(fout,"%s",pshdr);
fputs("%%Pages: 1 1\n",fout);
if(pcdname) fprintf(fout,"%%%%Title: %s\n",pcdname);
fputs("%%EndComments\n\n",fout);
fprintf(fout,"%f %f translate\n",x-scale*pixw/2.0,y-scale*pixh/2.0);
fprintf(fout,"%f %f scale\n",scale*pixw,scale*pixh);
}
static void end_postscript(FILE *fout)
{
fputs("%%EOF\n\n",fout);
}
static void sub_psgrey(FILE *fout,dim w,dim h, uBYTE *ptr,sdim zeil,sdim pix)
{ dim x,y;
register uBYTE *p;
sINT c;
size_dependant(fout,w,h,PAPER_LEFT,PAPER_BOTTOM,PAPER_WIDTH,PAPER_HEIGHT);
fprintf(fout,"%d string\n",w);
fprintf(fout,"%d %d 8\n",w,h); /* always 8 bit per channel */
fprintf(fout,"[%d 0 0 %d 0 %d]\n",w,-h,h);
fputs("{currentfile 1 index readhexstring pop} image\n",fout);
c=0;
for(y=0;y<h;y++,ptr+=zeil)
for(p=ptr,x=0;x<w;x++,p+=pix)
{HEX(*p);
if(!(++c % 36)) fputs("\n",fout);
}
fputs("\npop\n\n",fout);
}
void write_epsgrey(FILE *fout,dim w,dim h, uBYTE *ptr,sdim zeil,sdim pix)
{
fputs("%!PS-Adobe-2.0 EPSF-2.0\n",fout);
sub_psgrey(fout,w,h, ptr,zeil,pix);
end_postscript(fout);
}
void write_psgrey(FILE *fout,dim w,dim h, uBYTE *ptr,sdim zeil,sdim pix)
{
fputs("%!PS-Adobe-2.0\n",fout);
sub_psgrey(fout,w,h, ptr,zeil,pix);
fputs("showpage\n",fout);
end_postscript(fout);
}
static void sub_psrgb(FILE *fout,dim w,dim h,
uBYTE *rptr,sdim rzeil,sdim rpix,
uBYTE *gptr,sdim gzeil,sdim gpix,
uBYTE *bptr,sdim bzeil,sdim bpix)
{ dim x,y;
register uBYTE *pr,*pg,*pb;
sINT c;
size_dependant(fout,w,h,PAPER_LEFT,PAPER_BOTTOM,PAPER_WIDTH,PAPER_HEIGHT);
fprintf(fout,"%d string\n",w*3);
fprintf(fout,"%d %d 8\n",w,h); /* always 8 bit per channel */
fprintf(fout,"[%d 0 0 %d 0 %d]\n",w,-h,h);
fputs("{currentfile 1 index readhexstring pop} false 3 colorimage\n",fout);
c=0;
for(y=0;y<h;y++,rptr+=rzeil,gptr+=gzeil,bptr+=bzeil)
for(pr=rptr,pg=gptr,pb=bptr,x=0;x<w;x++,pr+=rpix,pg+=gpix,pb+=bpix)
{HEX(*pr);HEX(*pg);HEX(*pb);
if(!(++c % 12)) fputs("\n",fout);
}
fputs("\npop\n\n",fout);
}
void write_epsrgb(FILE *fout,dim w,dim h,
uBYTE *rptr,sdim rzeil,sdim rpix,
uBYTE *gptr,sdim gzeil,sdim gpix,
uBYTE *bptr,sdim bzeil,sdim bpix)
{
fputs("%!PS-Adobe-2.0 EPSF-2.0\n",fout);
sub_psrgb(fout,w,h, rptr,rzeil,rpix,gptr,gzeil,gpix,bptr,bzeil,bpix);
end_postscript(fout);
}
void write_psrgb(FILE *fout,dim w,dim h,
uBYTE *rptr,sdim rzeil,sdim rpix,
uBYTE *gptr,sdim gzeil,sdim gpix,
uBYTE *bptr,sdim bzeil,sdim bpix)
{
fputs("%!PS-Adobe-2.0\n",fout);
sub_psrgb(fout,w,h, rptr,rzeil,rpix,gptr,gzeil,gpix,bptr,bzeil,bpix);
fputs("showpage\n",fout);
end_postscript(fout);
}
typedef sINT dt;
extern sINT dithtab[];
#define DS 4
#define DA (1<<(DS-1))
#define DT 127
static void fakcopy(dim worig,dim horig, uBYTE *ptr1,sdim zeil,sdim pix,
sdim wx,sINT zn,dt *dest)
{FLTPT owf,ohf,wbruch,hbruch,m1,m2,ha,hb;
dim owd,ohd,x;
uBYTE *ptr2;
sINT md;
ohf=zn/PRINTER_FAK;
ohd=(dim)ohf;
hbruch=ohf-(FLTPT)ohd;
if(ohd>=horig) error(E_INTERN);
ptr1+=zeil*ohd;
ptr2= (ohd < horig - 1) ? ptr1+zeil : ptr1;
dest[-1]=DITH_NEUTR;
for(x=0;x<wx;x++)
{owf=x/PRINTER_FAK;
owd=(dim)owf;
wbruch=owf-(FLTPT)owd;
if(owd>=worig) error(E_INTERN);
if(owd<worig-1)
{ha=(FLTPT)ptr1[owd*pix];
hb=(FLTPT)ptr1[(owd+1)*pix];
m1=ha+wbruch*(hb-ha);
ha=(FLTPT)ptr2[owd*pix];
hb=(FLTPT)ptr2[(owd+1)*pix];
m2=ha+wbruch*(hb-ha);
}
else
{ m1=(FLTPT)ptr1[owd*pix];
m2=(FLTPT)ptr2[owd*pix];
}
md=(sINT)(m1+hbruch*(m2-m1));
if(md<0 || md>255) {fprintf(stderr,"md %d\n",md); error(E_INTERN);}
*(dest++)=dithtab[md];
}
dest[0]=DITH_NEUTR;
}
static void sub_psdith(FILE *fout,dim worig,dim horig, uBYTE *ptr,sdim zeil,sdim pix)
{ register uBYTE *p;
sINT c,i,ii,j,reg,bit;
dt new,diff;
dt *dP1,*dP2,*akt,*nex,*help,*rrun;
dim ww=0,wl=0,wr=0,hh=0,ho=0,hu=0,wx=0,hx=0;
int ccase;
FLTPT PW=0.0,PH=0.0;
#define copy(n,d) {if(FAK_SET) fakcopy(worig,horig,ptr,zeil,pix,wx,n,d); \
else{p=ptr+((n)*zeil); rrun=d;\
for(ii=0;ii<wx;ii++,p+=pix,rrun++) *rrun = dithtab[*p]; \
d[-1]=d[wx]=DITH_NEUTR; }}
#define pr(x) { reg= (reg<<1) | x; bit++; \
if(bit==8) {HEX(reg); \
if(!(++c % 36)) fputs("\n",fout);\
bit=reg=0;}}
#define flush { while(bit) pr(1); }
#define fill pr(1)
#define MakeFit(wi,he) { ww=(wi+7) & (~7); wl=(ww-wi)/2; wr=ww-wi-wl; \
hh=(he+7) & (~7); ho=(hh-he)/2; hu=hh-he-ho; }
ccase=( FAK_SET ? 4 : 0 ) |
( DPI_SET ? 2 : 0 ) |
( PSIZE_SET ? 1 : 0 ) ;
switch (ccase)
{case 0: /* no option or -dpi option */
case 2: hx=horig;
wx=worig;
MakeFit(wx,hx);
PW=ww*72.0/PRINTER_XDPI;
PH=hh*72.0/PRINTER_YDPI;
break;
case 1: /* paper size set with -pw and/or -ph */
hx=horig;
wx=worig;
MakeFit(wx,hx);
PW=PAPER_WIDTH;
PH=PAPER_HEIGHT;
break;
case 6: /* -fak option (and perhaps -dpi) */
case 4: hx=PRINTER_FAK*horig+0.5;
wx=PRINTER_FAK*worig+0.5;
MakeFit(wx,hx);
PW=ww*72.0/PRINTER_XDPI;
PH=hh*72.0/PRINTER_YDPI;
break;
case 5: /* -fak and papersize */
hx=PRINTER_FAK*horig+0.5;
wx=PRINTER_FAK*worig+0.5;
MakeFit(wx,hx);
PW=PAPER_WIDTH;
PH=PAPER_HEIGHT;
break;
case 3: /* papersize and dpi set, probably the most important case */
PW=PAPER_WIDTH;
PH=PAPER_HEIGHT;
FAK_SET=1;
{FLTPT fw,fh;
fw=PW/72.0*PRINTER_XDPI/worig;
fh=PH/72.0*PRINTER_YDPI/horig;
PRINTER_FAK=MIN(fw,fh);
}
hx=PRINTER_FAK*horig+0.5;
wx=PRINTER_FAK*worig+0.5;
MakeFit(wx,hx);
PW=ww*72.0/PRINTER_XDPI;
PH=hh*72.0/PRINTER_YDPI;
break;
case 7: /* size, dpi and factor set, this case should have been
cought earlier... */
default: error(E_INTERN);
};
if(FAK_SET && (PRINTER_FAK<=0.0 || PRINTER_FAK >=1000.0)) error(E_PRPAR);
if(PW<=0.0 || PH<=0.0) error(E_PRPAR);
if(wx < 4 || hx < 4) error(E_PRPAR);
if (!(dP1=(dt *)malloc((wx+2)*sizeof(dt)))) error(E_MEM);
if (!(dP2=(dt *)malloc((wx+2)*sizeof(dt)))) error(E_MEM);
size_dependant(fout,ww,hh,PAPER_LEFT,PAPER_BOTTOM,PW,PH);
fprintf(fout,"%d string\n",ww);
fprintf(fout,"%d %d 1\n",ww,hh); /* always 8 bit per channel */
fprintf(fout,"[%d 0 0 %d 0 %d]\n",ww,-hh,hh);
fputs("{currentfile 1 index readhexstring pop} image\n",fout);
c=bit=reg=0;
akt=dP1+1;
nex=dP2+1;
for(i=0;i<ho;i++)
for(j=0;j<ww;j++)
fill;
copy(0,nex);
for(i=0;i<hx;i++)
{help=akt; akt=nex; nex=help;
if(i<hx-1) copy(i+1,nex);
if(i&1)
for(j=0;j<wx;j++)
{ new=akt[j]>DT ? 255 : 0;
diff = akt[j]-new;
akt[j]=new;
akt[j+1]+=(diff*7 + DA)>>DS;
nex[j+1]+=(diff + DA)>>DS;
nex[j ]+=(diff*5 + DA)>>DS;
nex[j-1]+=(diff*3 + DA)>>DS;
}
else
for(j=wx-1;j>=0;j--)
{ new=akt[j]>DT ? 255 : 0;
diff = akt[j]-new;
akt[j]=new;
akt[j-1]+=(diff*7 + DA)>>DS;
nex[j-1]+=(diff + DA)>>DS;
nex[j ]+=(diff*5 + DA)>>DS;
nex[j+1]+=(diff*3 + DA)>>DS;
}
for(j=0;j<wl;j++) fill;
for(j=0;j<wx;j++)
{if (akt[j]>DT) { pr(1); }
else { pr(0); }
}
for(j=0;j<wr;j++) fill;
flush;
}
for(i=0;i<hu;i++)
for(j=0;j<ww;j++)
fill;
flush;
fputs("\npop\n\n",fout);
free(dP1);
free(dP2);
}
void write_epsdith(FILE *fout,dim w,dim h, uBYTE *ptr,sdim zeil,sdim pix)
{
fputs("%!PS-Adobe-2.0 EPSF-2.0\n",fout);
sub_psdith(fout,w,h, ptr,zeil,pix);
end_postscript(fout);
}
void write_psdith(FILE *fout,dim w,dim h, uBYTE *ptr,sdim zeil,sdim pix)
{
fputs("%!PS-Adobe-2.0\n",fout);
sub_psdith(fout,w,h, ptr,zeil,pix);
fputs("showpage\n",fout);
end_postscript(fout);
}